package scalalang.reflection

object Trees extends App {
  import scala.reflect.runtime.universe._

  val tree = Apply(Select(Ident(newTermName("x")), newTermName("$plus")), List(Literal(Constant(2))))
  println(show(tree))
  println(showRaw(tree))

  val (fun, arg) = tree match {
    case Apply(fn, a :: Nil) => (fn, a)
  }
  val Apply(fun2, ar2g :: Nil) = tree

  val expr = reify { class Flower { def name = "Rose" } }
  println(expr.tree)

  val tree2 = Apply(Select(Apply(Select(Ident(newTermName("x")), newTermName("$plus")), List(Literal(Constant(2)))), newTermName("$plus")), List(Literal(Constant(3))))
  object traverser extends Traverser { //广度
    var applies = List[Apply]()
    override def traverse(tree: Tree): Unit = tree match {
      case app @ Apply(fun, args) =>
        applies = app :: applies
        super.traverse(fun)
        super.traverseTrees(args)
      case _ => super.traverse(tree)
    }
  }

  println(traverser(tree2) -> traverser.applies)
  //
  val x = reify(2)
  reify(println(x.splice))

  //   val fn = reify(println)
  //   reify(fn.splice(2)) cannt
  import scala.tools.reflect.ToolBox
  val tb = runtimeMirror(getClass.getClassLoader).mkToolBox()
  println(showRaw(tb.parse("println(2)"))) //Apply(Ident(newTermName("println")), List(Literal(Constant(2)))) println未绑
  //
  import language.experimental.macros

//  Macros1.test

  val tree3 = reify { "test".length }.tree
  val ttree = tb.typeCheck(tree3)
  println(ttree.tpe -> ttree.symbol)
}